﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Advance
{
    public static class Util
    {
        /// <summary>
        /// Serializes an object to a binary representation, returned as a byte array.
        /// </summary>
        /// <param name="Object">The object to serialize.</param>
        public static byte[] Serialize(object Object)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, Object);
                return stream.ToArray();
            }
        }

        /// <summary>
        /// Deserializes an object from a binary representation.
        /// </summary>
        /// <param name="binaryObject">The byte array to deserialize.</param>
        public static object Deserialize(byte[] binaryObject)
        {
            using (MemoryStream stream = new MemoryStream(binaryObject))
            {
                return new BinaryFormatter().Deserialize(stream);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Person somePerson = new Person();
            somePerson.Name = "Justin";
            somePerson.Age = 18;
            somePerson.Connection = new NetConnection("128.0.0.5", 1234);
            byte[] data = Util.Serialize(somePerson);
            Person anotherPerson = new Person();
            anotherPerson = Util.Deserialize(data) as Person;
            Console.WriteLine(anotherPerson.ToString());
            Console.ReadKey();
        }
    }

    [Serializable()]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public NetConnection Connection;

        public override string ToString()
        {
            return string.Format("Name: {0}, Age: {1}, Connection: {2}", Name, Age, Connection.ToString());
        }
    }

    [Serializable()]
    public class NetConnection
    {
        public string IP { get; set; }
        public int Port { get; set; }

        public NetConnection(string ip, int port)
        {
            IP = ip;
            Port = port;
        }

        public override string ToString()
        {
            return string.Format("IP: {0}, Port: {1}", IP, Port);
        }
    }
}
